<script setup>
import { ref, reactive } from 'vue'

// 上传状态
const uploadStatus = ref('ready') // ready, uploading, success, error
const uploadProgress = ref(0)
const dragover = ref(false)

// 图片列表
const imageList = reactive([])

// 拖拽事件处理
const handleDragover = (e) => {
  e.preventDefault()
  dragover.value = true
}

const handleDragleave = (e) => {
  e.preventDefault()
  dragover.value = false
}

const handleDrop = (e) => {
  e.preventDefault()
  dragover.value = false
  const files = e.dataTransfer.files
  if (files.length > 0) {
    handleFiles(files)
  }
}

// 处理选择的文件
const handleFileSelect = (e) => {
  const files = e.target.files
  if (files.length > 0) {
    handleFiles(files)
  }
}

// 处理文件上传
const handleFiles = (files) => {
  for (let i = 0; i < files.length; i++) {
    const file = files[i]
    // 检查是否为图片
    if (!file.type.match('image.*')) {
      continue
    }
    
    // 预览图片
    const reader = new FileReader()
    reader.onload = (e) => {
      const imgObj = {
        id: Date.now() + i,
        name: file.name,
        size: formatFileSize(file.size),
        preview: e.target.result,
        status: 'ready', // ready, uploading, success, error
        progress: 0,
        url: '',
        file: file
      }
      imageList.push(imgObj)
    }
    reader.readAsDataURL(file)
  }
}

// 上传图片
const uploadImages = () => {
  if (imageList.length === 0) {
    return
  }
  
  uploadStatus.value = 'uploading'
  
  // 模拟上传进度
  // 实际项目中这里应该调用API上传图片
  const timer = setInterval(() => {
    uploadProgress.value += 5
    
    // 更新每张图片的上传进度
    imageList.forEach(img => {
      if (img.status === 'ready') {
        img.status = 'uploading'
      }
      if (img.status === 'uploading') {
        img.progress = uploadProgress.value
        if (img.progress >= 100) {
          img.progress = 100
          img.status = 'success'
          img.url = `https://example.com/images/${img.id}`
        }
      }
    })
    
    if (uploadProgress.value >= 100) {
      clearInterval(timer)
      uploadProgress.value = 100
      uploadStatus.value = 'success'
    }
  }, 200)
}

// 移除图片
const removeImage = (id) => {
  const index = imageList.findIndex(img => img.id === id)
  if (index !== -1) {
    imageList.splice(index, 1)
  }
}

// 复制链接
const copyLink = (url) => {
  navigator.clipboard.writeText(url)
    .then(() => {
      alert('链接已复制到剪贴板')
    })
    .catch(err => {
      console.error('复制失败:', err)
    })
}

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i]
}
</script>

<template>
  <div class="upload-container">
    <!-- 标题 -->
    <div class="page-header">
      <h2>图片上传</h2>
      <p class="desc">支持拖拽上传或点击选择文件</p>
    </div>
    
    <!-- 上传区域 -->
    <div 
      class="upload-area" 
      :class="{ 'dragover': dragover }"
      @drop="handleDrop"
      @dragover="handleDragover"
      @dragleave="handleDragleave"
    >
      <div class="upload-content">
        <div class="upload-icon">
          <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
            <polyline points="17 8 12 3 7 8"></polyline>
            <line x1="12" y1="3" x2="12" y2="15"></line>
          </svg>
        </div>
        <div class="upload-text">
          拖拽图片到此处或
          <label class="file-select">
            点击选择
            <input type="file" multiple accept="image/*" @change="handleFileSelect" />
          </label>
        </div>
      </div>
    </div>
    
    <!-- 图片列表 -->
    <div class="image-list" v-if="imageList.length > 0">
      <div class="list-header">
        <h3>图片列表</h3>
        <button class="upload-btn" @click="uploadImages" :disabled="uploadStatus === 'uploading'">
          {{ uploadStatus === 'ready' ? '开始上传' : uploadStatus === 'uploading' ? '上传中...' : '上传完成' }}
        </button>
      </div>
      
      <!-- 总进度条 -->
      <div class="progress-bar" v-if="uploadStatus === 'uploading' || uploadStatus === 'success'">
        <div class="progress" :style="{ width: uploadProgress + '%' }"></div>
        <span class="progress-text">{{ uploadProgress }}%</span>
      </div>
      
      <!-- 图片项 -->
      <div class="image-items">
        <div class="image-item" v-for="image in imageList" :key="image.id">
          <div class="image-preview">
            <img :src="image.preview" :alt="image.name" />
          </div>
          <div class="image-info">
            <div class="image-name">{{ image.name }}</div>
            <div class="image-size">{{ image.size }}</div>
            <div class="image-status">
              <!-- 状态进度条 -->
              <div class="item-progress-bar" v-if="image.status !== 'ready'">
                <div class="item-progress" :style="{ width: image.progress + '%' }" :class="{ 'success': image.status === 'success' }"></div>
                <span class="item-progress-text">{{ image.progress }}%</span>
              </div>
              <div class="status-text" v-else>待上传</div>
            </div>
          </div>
          <div class="image-actions">
            <button class="action-btn remove" @click="removeImage(image.id)" title="删除">
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <polyline points="3 6 5 6 21 6"></polyline>
                <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
                <line x1="10" y1="11" x2="10" y2="17"></line>
                <line x1="14" y1="11" x2="14" y2="17"></line>
              </svg>
            </button>
            <button class="action-btn copy" v-if="image.status === 'success'" @click="copyLink(image.url)" title="复制链接">
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
                <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
              </svg>
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.upload-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

.page-header {
  margin-bottom: 24px;
}

h2 {
  margin: 0 0 8px;
  font-size: 24px;
  font-weight: 500;
}

.desc {
  color: #606266;
  margin: 0;
}

.upload-area {
  border: 2px dashed #dcdfe6;
  border-radius: 8px;
  background-color: #fff;
  padding: 40px;
  text-align: center;
  cursor: pointer;
  transition: all 0.3s;
}

.upload-area.dragover {
  border-color: #409EFF;
  background-color: rgba(64, 158, 255, 0.1);
}

.upload-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.upload-icon {
  color: #909399;
  margin-bottom: 16px;
}

.upload-text {
  color: #606266;
  font-size: 16px;
}

.file-select {
  color: #409EFF;
  cursor: pointer;
}

.file-select input {
  display: none;
}

.image-list {
  margin-top: 24px;
  background-color: #fff;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.list-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 500;
}

.upload-btn {
  background-color: #409EFF;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
}

.upload-btn:hover {
  background-color: #66b1ff;
}

.upload-btn:disabled {
  background-color: #a0cfff;
  cursor: not-allowed;
}

.progress-bar {
  height: 8px;
  background-color: #ebeef5;
  border-radius: 100px;
  margin-bottom: 20px;
  position: relative;
}

.progress {
  height: 100%;
  background-color: #409EFF;
  border-radius: 100px;
  transition: width 0.3s;
}

.progress-text {
  position: absolute;
  top: -20px;
  right: 0;
  font-size: 12px;
  color: #606266;
}

.image-items {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
}

.image-item {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  overflow: hidden;
  transition: all 0.3s;
}

.image-item:hover {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.image-preview {
  height: 200px;
  overflow: hidden;
  background-color: #f5f7fa;
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.image-info {
  padding: 12px;
}

.image-name {
  font-size: 14px;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.image-size {
  font-size: 12px;
  color: #909399;
  margin-bottom: 8px;
}

.item-progress-bar {
  height: 4px;
  background-color: #ebeef5;
  border-radius: 100px;
  position: relative;
}

.item-progress {
  height: 100%;
  background-color: #e6a23c;
  border-radius: 100px;
}

.item-progress.success {
  background-color: #67c23a;
}

.item-progress-text {
  position: absolute;
  right: 0;
  top: -18px;
  font-size: 12px;
  color: #606266;
}

.status-text {
  font-size: 12px;
  color: #909399;
}

.image-actions {
  display: flex;
  justify-content: flex-end;
  padding: 8px 12px;
  border-top: 1px solid #ebeef5;
}

.action-btn {
  background: none;
  border: none;
  color: #909399;
  cursor: pointer;
  padding: 4px;
  margin-left: 8px;
  border-radius: 4px;
  transition: all 0.3s;
}

.action-btn:hover {
  background-color: #f2f6fc;
}

.action-btn.remove:hover {
  color: #f56c6c;
}

.action-btn.copy:hover {
  color: #409EFF;
}
</style>


